#!/usr/bin/env python3
"""
存储引擎综合测试程序

测试存储引擎的所有功能：
1. 基础页管理功能
2. 缓存策略测试
3. 表结构管理
4. 记录级CRUD操作
5. 数据持久化验证
6. 性能测试
7. 并发场景测试
"""

import os
import sys
import time
import tempfile
import unittest
from typing import List, Dict, Any

# 添加当前目录到Python路径
current_dir = os.path.dirname(os.path.abspath(__file__))
if current_dir not in sys.path:
    sys.path.insert(0, current_dir)

from storage_engine import StorageEngine, CachePolicy
from table_schema import TableSchema, Column, ColumnType, Record
from constants import PAGE_SIZE


class ComprehensiveStorageTest(unittest.TestCase):
    """存储引擎综合测试类"""
    
    def setUp(self):
        """每个测试前的准备"""
        import uuid
        # 使用UUID确保每个测试都有唯一的数据库文件
        unique_suffix = str(uuid.uuid4())[:8]
        self.temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=f'_{unique_suffix}.db')
        self.db_path = self.temp_file.name
        self.temp_file.close()
        
    def tearDown(self):
        """每个测试后的清理"""
        if os.path.exists(self.db_path):
            os.unlink(self.db_path)
    
    def test_01_basic_page_operations(self):
        """测试基础页操作"""
        print("\n🧪 测试基础页操作...")
        
        with StorageEngine(self.db_path) as engine:
            # 测试页分配
            page_ids = []
            for i in range(5):
                page_id = engine.allocate_page()
                self.assertGreaterEqual(page_id, 3)  # 前几个页面被系统使用
                page_ids.append(page_id)
            
            # 测试页写入和读取
            test_data = b"Hello World! " * 300  # 大约4KB数据
            test_data = test_data[:PAGE_SIZE]  # 确保不超过页大小
            
            success = engine.write_page(page_ids[0], test_data)
            self.assertTrue(success)
            
            read_data = engine.read_page(page_ids[0])
            self.assertEqual(read_data[:len(test_data)], test_data)
            
            # 测试页释放
            for page_id in page_ids[3:]:  # 释放最后两个页面
                success = engine.deallocate_page(page_id)
                self.assertTrue(success)
        
        print("   ✅ 基础页操作测试通过")
    
    def test_02_cache_strategies(self):
        """测试不同缓存策略"""
        print("\n🧪 测试缓存策略...")
        
        cache_policies = [CachePolicy.LRU, CachePolicy.FIFO, CachePolicy.CLOCK]
        
        for policy in cache_policies:
            with StorageEngine(self.db_path, cache_size=3, cache_policy=policy) as engine:
                # 分配测试页面
                page_ids = [engine.allocate_page() for _ in range(5)]
                
                # 写入测试数据
                for i, page_id in enumerate(page_ids):
                    data = f"Data for page {i}".encode('utf-8')
                    data = data + bytes(PAGE_SIZE - len(data))
                    engine.put_page(page_id, data)
                
                # 模拟访问模式测试缓存
                access_pattern = [0, 1, 2, 3, 1, 4, 0, 2]
                for idx in access_pattern:
                    if idx < len(page_ids):
                        engine.get_page(page_ids[idx])
                
                # 检查缓存统计
                cache_stats = engine.get_cache_stats()
                self.assertGreater(cache_stats.total_requests, 0)
                
        print(f"   ✅ 缓存策略测试通过 ({len(cache_policies)}种策略)")
    
    def test_03_table_schema_management(self):
        """测试表结构管理"""
        print("\n🧪 测试表结构管理...")
        
        with StorageEngine(self.db_path) as engine:
            # 创建测试表
            columns = [
                Column("id", ColumnType.INT, nullable=False, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=100, nullable=False),
                Column("age", ColumnType.INT, nullable=True),
                Column("salary", ColumnType.FLOAT, nullable=True),
                Column("is_active", ColumnType.BOOLEAN, nullable=False),
                Column("description", ColumnType.CHAR, length=200, nullable=True)
            ]
            
            # 创建表
            success = engine.create_table("employees", columns)
            self.assertTrue(success)
            
            # 验证表存在
            self.assertTrue(engine.table_exists("employees"))
            self.assertFalse(engine.table_exists("nonexistent"))
            
            # 获取表结构
            schema = engine.get_table_schema("employees")
            self.assertIsNotNone(schema)
            self.assertEqual(schema.table_name, "employees")
            self.assertEqual(len(schema.columns), 6)
            
            # 获取表列表
            tables = engine.get_table_list()
            self.assertIn("employees", tables)
            
            # 创建重复表应该失败
            success = engine.create_table("employees", columns)
            self.assertFalse(success)
        
        print("   ✅ 表结构管理测试通过")
    
    def test_04_record_crud_operations(self):
        """测试记录CRUD操作"""
        print("\n🧪 测试记录CRUD操作...")
        
        with StorageEngine(self.db_path) as engine:
            # 创建测试表
            columns = [
                Column("student_id", ColumnType.INT, nullable=False, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=50, nullable=False),
                Column("major", ColumnType.VARCHAR, length=30, nullable=True),
                Column("gpa", ColumnType.FLOAT, nullable=True),
                Column("is_graduate", ColumnType.BOOLEAN, nullable=False)
            ]
            
            engine.create_table("students", columns)
            
            # 插入测试数据
            students_data = [
                {"student_id": 1, "name": "张三", "major": "计算机科学", "gpa": 3.8, "is_graduate": False},
                {"student_id": 2, "name": "李四", "major": "数学", "gpa": 3.6, "is_graduate": False},
                {"student_id": 3, "name": "王五", "major": "物理", "gpa": 3.9, "is_graduate": True},
                {"student_id": 4, "name": "赵六", "major": None, "gpa": None, "is_graduate": False}
            ]
            
            # 测试插入
            for student in students_data:
                success = engine.insert_record("students", student)
                self.assertTrue(success)
            
            # 测试查询所有记录
            all_students = engine.select_records("students")
            self.assertEqual(len(all_students), 4)
            
            # 验证记录内容
            found_zhang_san = False
            for student in all_students:
                if student["name"] == "张三":
                    found_zhang_san = True
                    self.assertEqual(student["student_id"], 1)
                    self.assertEqual(student["major"], "计算机科学")
                    self.assertAlmostEqual(student["gpa"], 3.8, places=1)
                    self.assertEqual(student["is_graduate"], False)
            
            self.assertTrue(found_zhang_san)
            
            # 测试条件查询
            graduates = engine.select_records("students", {"is_graduate": True})
            self.assertEqual(len(graduates), 1)
            self.assertEqual(graduates[0]["name"], "王五")
            
        print("   ✅ 记录CRUD操作测试通过")
    
    def test_05_data_persistence(self):
        """测试数据持久化"""
        print("\n🧪 测试数据持久化...")
        
        # 第一阶段：创建数据
        with StorageEngine(self.db_path) as engine:
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=50),
                Column("score", ColumnType.FLOAT)
            ]
            
            engine.create_table("test_persistence", columns)
            
            test_records = [
                {"id": 1, "name": "测试1", "score": 95.5},
                {"id": 2, "name": "测试2", "score": 87.3},
                {"id": 3, "name": "测试3", "score": 92.1}
            ]
            
            for record in test_records:
                engine.insert_record("test_persistence", record)
        
        # 第二阶段：验证持久化
        with StorageEngine(self.db_path) as engine:
            # 验证表结构持久化
            self.assertTrue(engine.table_exists("test_persistence"))
            
            schema = engine.get_table_schema("test_persistence")
            self.assertIsNotNone(schema)
            self.assertEqual(len(schema.columns), 3)
            
            # 验证数据持久化
            records = engine.select_records("test_persistence")
            self.assertEqual(len(records), 3)
            
            # 验证具体数据
            record_dict = {r["id"]: r for r in records}
            self.assertEqual(record_dict[1]["name"], "测试1")
            self.assertAlmostEqual(record_dict[1]["score"], 95.5, places=1)
            self.assertEqual(record_dict[2]["name"], "测试2")
            self.assertAlmostEqual(record_dict[2]["score"], 87.3, places=1)
        
        print("   ✅ 数据持久化测试通过")
    
    def test_06_data_types_handling(self):
        """测试不同数据类型处理"""
        print("\n🧪 测试数据类型处理...")
        
        with StorageEngine(self.db_path) as engine:
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=50),
                Column("description", ColumnType.CHAR, length=100),
                Column("price", ColumnType.FLOAT),
                Column("is_available", ColumnType.BOOLEAN),
                Column("optional_field", ColumnType.VARCHAR, length=30, nullable=True)
            ]
            
            engine.create_table("products", columns)
            
            # 测试各种数据类型
            test_record = {
                "id": 1,
                "name": "测试产品",
                "description": "这是一个测试产品的详细描述",
                "price": 99.99,
                "is_available": True,
                "optional_field": None  # 测试NULL值
            }
            
            success = engine.insert_record("products", test_record)
            self.assertTrue(success)
            
            # 验证数据
            records = engine.select_records("products")
            self.assertEqual(len(records), 1)
            
            record = records[0]
            self.assertEqual(record["id"], 1)
            self.assertEqual(record["name"], "测试产品")
            self.assertEqual(record["description"].strip(), "这是一个测试产品的详细描述")
            self.assertAlmostEqual(record["price"], 99.99, places=2)
            self.assertEqual(record["is_available"], True)
            self.assertIsNone(record["optional_field"])
        
        print("   ✅ 数据类型处理测试通过")
    
    def test_07_multiple_tables(self):
        """测试多表操作"""
        print("\n🧪 测试多表操作...")
        
        with StorageEngine(self.db_path) as engine:
            # 使用唯一的表名避免冲突
            student_table = "multi_students"
            course_table = "multi_courses"
            
            # 确保表是干净的
            if engine.table_exists(student_table):
                engine.drop_table(student_table)
            if engine.table_exists(course_table):
                engine.drop_table(course_table)
            
            # 创建学生表
            student_columns = [
                Column("student_id", ColumnType.INT, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=50)
            ]
            engine.create_table(student_table, student_columns)
            
            # 创建课程表
            course_columns = [
                Column("course_id", ColumnType.INT, primary_key=True),
                Column("course_name", ColumnType.VARCHAR, length=100),
                Column("credits", ColumnType.INT)
            ]
            engine.create_table(course_table, course_columns)
            
            # 插入数据
            engine.insert_record(student_table, {"student_id": 1, "name": "学生A"})
            engine.insert_record(student_table, {"student_id": 2, "name": "学生B"})
            
            engine.insert_record(course_table, {"course_id": 101, "course_name": "数据库系统", "credits": 3})
            engine.insert_record(course_table, {"course_id": 102, "course_name": "操作系统", "credits": 4})
            
            # 验证两个表都工作正常
            students = engine.select_records(student_table)
            courses = engine.select_records(course_table)
            
            self.assertEqual(len(students), 2)
            self.assertEqual(len(courses), 2)
            
            # 验证表列表
            tables = engine.get_table_list()
            self.assertIn(student_table, tables)
            self.assertIn(course_table, tables)
            
            # 删除一个表
            success = engine.drop_table(student_table)
            self.assertTrue(success)
            
            # 验证表已删除
            self.assertFalse(engine.table_exists(student_table))
            self.assertTrue(engine.table_exists(course_table))
            
            # 课程表应该仍然工作
            courses = engine.select_records(course_table)
            self.assertEqual(len(courses), 2)
        
        print("   ✅ 多表操作测试通过")
    
    def test_08_performance_test(self):
        """性能测试"""
        print("\n🧪 运行性能测试...")
        
        with StorageEngine(self.db_path, cache_size=50) as engine:
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("data", ColumnType.VARCHAR, length=100)
            ]
            
            # 使用唯一的表名
            import time
            import uuid
            table_name = f"performance_test_{int(time.time() * 1000000) % 1000000}_{str(uuid.uuid4())[:8]}"
            
            # 确保表不存在
            if engine.table_exists(table_name):
                engine.drop_table(table_name)
            
            engine.create_table(table_name, columns)
            
            # 插入大量数据
            num_records = 100
            start_time = time.time()
            
            for i in range(num_records):
                record = {"id": i, "data": f"测试数据_{i:04d}"}
                engine.insert_record(table_name, record)
            
            insert_time = time.time() - start_time
            
            # 查询测试
            start_time = time.time()
            all_records = engine.select_records(table_name)
            query_time = time.time() - start_time
            
            # 验证结果
            if len(all_records) != num_records:
                print(f"   ❌ 记录数量不匹配: 期望{num_records}，实际{len(all_records)}")
                print(f"   📋 表名: {table_name}")
                print(f"   📂 数据库文件: {self.db_path}")
                
                # 检查是否有重复的ID
                if len(all_records) > 0:
                    ids = [r["id"] for r in all_records]
                    unique_ids = set(ids)
                    print(f"   🔢 总记录数: {len(ids)}")
                    print(f"   🔢 唯一ID数: {len(unique_ids)}")
                    print(f"   🔢 ID范围: {min(ids)} - {max(ids)}")
                    
                    if len(ids) != len(unique_ids):
                        print("   ⚠️  发现重复的ID!")
                        from collections import Counter
                        id_counts = Counter(ids)
                        duplicates = {id_val: count for id_val, count in id_counts.items() if count > 1}
                        print(f"   🔁 重复ID: {dict(list(duplicates.items())[:5])}")  # 只显示前5个
                    
                    # 显示表页面信息
                    page_ids = engine.table_pages.get(table_name, [])
                    print(f"   📄 表页面数: {len(page_ids)}")
                    print(f"   📄 页面ID: {page_ids}")
            
            self.assertEqual(len(all_records), num_records, f"记录数量不匹配: 期望{num_records}，实际{len(all_records)}")
            
            # 输出性能统计
            cache_stats = engine.get_cache_stats()
            storage_stats = engine.get_storage_stats()
            
            print(f"   📊 性能统计:")
            print(f"      插入{num_records}条记录耗时: {insert_time:.3f}秒")
            print(f"      查询{num_records}条记录耗时: {query_time:.3f}秒")
            print(f"      缓存命中率: {cache_stats.hit_rate:.1%}")
            print(f"      总页数: {storage_stats.total_pages}")
            print(f"      已用页数: {storage_stats.used_pages}")
        
        print("   ✅ 性能测试通过")
    
    def test_09_edge_cases(self):
        """边界情况测试"""
        print("\n🧪 测试边界情况...")
        
        with StorageEngine(self.db_path) as engine:
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("text", ColumnType.VARCHAR, length=50, nullable=True)
            ]
            
            # 确保表是干净的
            table_name = "edge_test"
            if engine.table_exists(table_name):
                engine.drop_table(table_name)
            
            engine.create_table(table_name, columns)
            
            # 先测试基本插入和查询
            test_records = [
                {"id": 1, "text": ""},
                {"id": 2, "text": None}, 
                {"id": 3, "text": "test"}
            ]
            
            # 逐个插入并验证
            for test_record in test_records:
                success = engine.insert_record(table_name, test_record)
                self.assertTrue(success, f"插入记录失败: {test_record}")
            
            # 验证数据
            records = engine.select_records(table_name)
            self.assertEqual(len(records), 3, f"期望3条记录，实际{len(records)}条")
            
            # 打印调试信息
            print(f"   调试信息 - 查询到的记录:")
            for i, record in enumerate(records):
                print(f"     记录{i}: {record}")
            
            record_dict = {r["id"]: r for r in records}
            
            # 检查记录是否存在
            if 1 not in record_dict:
                self.fail(f"记录ID 1 不存在，实际记录IDs: {list(record_dict.keys())}")
            if 2 not in record_dict:
                self.fail(f"记录ID 2 不存在，实际记录IDs: {list(record_dict.keys())}")
            if 3 not in record_dict:
                self.fail(f"记录ID 3 不存在，实际记录IDs: {list(record_dict.keys())}")
            
            # 验证具体值
            self.assertEqual(record_dict[1]["text"], "", f"记录1的text应该是空字符串，实际: {repr(record_dict[1]['text'])}")
            self.assertIsNone(record_dict[2]["text"], f"记录2的text应该是None，实际: {repr(record_dict[2]['text'])}")
            self.assertEqual(record_dict[3]["text"], "test", f"记录3的text应该是'test'，实际: {repr(record_dict[3]['text'])}")
            
            # 测试最大长度字符串（单独测试）
            max_text = "A" * 50
            success = engine.insert_record(table_name, {"id": 4, "text": max_text})
            self.assertTrue(success, "插入最大长度字符串失败")
            
            records = engine.select_records(table_name)
            record_dict = {r["id"]: r for r in records}
            if 4 in record_dict:
                self.assertEqual(record_dict[4]["text"], max_text, "最大长度字符串验证失败")
            
            # 测试不存在的表操作
            success = engine.insert_record("nonexistent", {"id": 1})
            self.assertFalse(success)
            
            records = engine.select_records("nonexistent")
            self.assertEqual(len(records), 0)
        
        print("   ✅ 边界情况测试通过")
    
    def test_10_complex_queries(self):
        """复杂查询条件测试"""
        print("\n🧪 测试复杂查询条件...")
        
        with StorageEngine(self.db_path) as engine:
            # 创建测试表
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=50),
                Column("age", ColumnType.INT),
                Column("score", ColumnType.FLOAT),
                Column("department", ColumnType.VARCHAR, length=30, nullable=True),
                Column("active", ColumnType.BOOLEAN)
            ]
            
            table_name = "complex_query_test"
            if engine.table_exists(table_name):
                engine.drop_table(table_name)
            
            engine.create_table(table_name, columns)
            
            # 插入测试数据
            test_data = [
                {"id": 1, "name": "Alice", "age": 25, "score": 85.5, "department": "CS", "active": True},
                {"id": 2, "name": "Bob", "age": 30, "score": 92.0, "department": "CS", "active": True},
                {"id": 3, "name": "Charlie", "age": 22, "score": 78.5, "department": "Math", "active": False},
                {"id": 4, "name": "Diana", "age": 28, "score": 88.0, "department": None, "active": True},
                {"id": 5, "name": "Eve", "age": 35, "score": 95.5, "department": "Physics", "active": True},
                {"id": 6, "name": "Frank", "age": 24, "score": 82.0, "department": "CS", "active": False},
                {"id": 7, "name": "Grace", "age": 27, "score": 90.0, "department": "Math", "active": True},
                {"id": 8, "name": "Henry", "age": 26, "score": 76.5, "department": "Physics", "active": False}
            ]
            
            for data in test_data:
                success = engine.insert_record(table_name, data)
                self.assertTrue(success, f"插入记录失败: {data}")
            
            print("   📊 插入8条测试记录")
            
            # 测试1: 简单等值查询
            result = engine.select_records(table_name, {"department": "CS"})
            cs_students = [r for r in result if r["department"] == "CS"]
            self.assertEqual(len(result), 3, "CS部门学生数量错误")
            print(f"   ✓ 等值查询: CS部门有{len(result)}个学生")
            
            # 测试2: 比较操作符
            result = engine.select_records(table_name, {"age": {"$gt": 26}})
            self.assertEqual(len(result), 4, "年龄>26的学生数量错误")
            print(f"   ✓ 大于比较: 年龄>26的有{len(result)}个学生")
            
            # 测试3: 范围查询
            result = engine.select_records(table_name, {
                "$and": [
                    {"age": {"$gte": 25}},
                    {"age": {"$lte": 30}}
                ]
            })
            self.assertEqual(len(result), 5, "年龄25-30的学生数量错误")
            print(f"   ✓ 范围查询: 年龄25-30的有{len(result)}个学生")
            
            # 测试4: IN操作符
            result = engine.select_records(table_name, {
                "department": {"$in": ["CS", "Math"]}
            })
            self.assertEqual(len(result), 5, "CS或Math部门学生数量错误")
            print(f"   ✓ IN查询: CS或Math部门有{len(result)}个学生")
            
            # 测试5: LIKE模式匹配
            print("   🔍 调试LIKE查询...")
            all_names = [r["name"] for r in engine.select_records(table_name)]
            print(f"   📋 所有名字: {all_names}")
            
            result = engine.select_records(table_name, {
                "name": {"$like": "A%"}
            })
            print(f"   🔍 LIKE 'A%' 查询结果: {[r['name'] for r in result]}")
            self.assertEqual(len(result), 1, f"名字以A开头的学生数量错误，期望1个，实际{len(result)}个")
            print(f"   ✓ LIKE查询: 名字以A开头的有{len(result)}个学生")
            
            # 测试6: NULL值查询
            result = engine.select_records(table_name, {
                "department": {"$null": True}
            })
            self.assertEqual(len(result), 1, "部门为空的学生数量错误")
            print(f"   ✓ NULL查询: 部门为空的有{len(result)}个学生")
            
            # 测试7: 逻辑OR组合
            result = engine.select_records(table_name, {
                "$or": [
                    {"score": {"$gt": 90}},
                    {"age": {"$lt": 24}}
                ]
            })
            self.assertEqual(len(result), 3, "高分或年轻学生数量错误")
            print(f"   ✓ OR查询: 高分(>90)或年轻(<24)的有{len(result)}个学生")
            
            # 测试8: 复杂嵌套条件
            result = engine.select_records(table_name, {
                "$and": [
                    {"active": True},
                    {
                        "$or": [
                            {"department": "CS"},
                            {"score": {"$gte": 90}}
                        ]
                    }
                ]
            })
            self.assertEqual(len(result), 4, "复杂条件查询结果错误")
            print(f"   ✓ 复杂查询: 活跃且(CS部门或高分)的有{len(result)}个学生")
            
            # 测试9: NOT操作符
            result = engine.select_records(table_name, {
                "$not": {"department": "CS"}
            })
            # 应该返回非CS部门的学生（包括NULL）
            self.assertEqual(len(result), 5, "NOT查询结果错误")
            print(f"   ✓ NOT查询: 非CS部门的有{len(result)}个学生")
            
            # 测试10: 多字段复合条件
            result = engine.select_records(table_name, {
                "age": {"$gte": 25},
                "score": {"$gte": 85},
                "active": True
            })
            self.assertEqual(len(result), 5, "多字段条件查询结果错误")
            print(f"   ✓ 多字段查询: 年龄≥25且分数≥85且活跃的有{len(result)}个学生")
            
        print("   ✅ 复杂查询条件测试通过")
    
    def test_11_locking_mechanism(self):
        """锁机制测试"""
        print("\n🧪 测试锁机制...")
        
        # 测试启用锁的存储引擎
        with StorageEngine(self.db_path, enable_locking=True) as engine:
            # 创建测试表
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("data", ColumnType.VARCHAR, length=50)
            ]
            
            engine.create_table("lock_test", columns)
            
            # 检查锁管理器可用性
            lock_manager = engine.get_lock_manager()
            self.assertIsNotNone(lock_manager, "锁管理器应该可用")
            
            # 测试表级锁
            success = engine.acquire_table_lock("lock_test", "shared")
            self.assertTrue(success, "应该能够获取共享锁")
            
            # 获取锁信息
            lock_info = engine.get_lock_info()
            self.assertTrue(lock_info["locking_enabled"], "锁机制应该启用")
            self.assertGreater(lock_info["stats"]["current_locks"], 0, "应该有当前锁")
            
            # 释放锁
            success = engine.release_table_lock("lock_test")
            self.assertTrue(success, "应该能够释放锁")
            
            # 测试插入和查询在锁保护下的工作
            engine.insert_record("lock_test", {"id": 1, "data": "测试数据1"})
            engine.insert_record("lock_test", {"id": 2, "data": "测试数据2"})
            
            records = engine.select_records("lock_test")
            self.assertEqual(len(records), 2, "锁保护下的数据操作应该正常")
        
        # 测试禁用锁的存储引擎
        with StorageEngine(self.db_path.replace('.db', '_nolock.db'), enable_locking=False) as engine_no_lock:
            columns = [Column("id", ColumnType.INT, primary_key=True)]
            engine_no_lock.create_table("no_lock_test", columns)
            
            # 尝试获取锁应该失败
            success = engine_no_lock.acquire_table_lock("no_lock_test", "shared")
            self.assertFalse(success, "禁用锁时不应该能获取锁")
            
            # 但数据操作应该正常
            success = engine_no_lock.insert_record("no_lock_test", {"id": 1})
            self.assertTrue(success, "禁用锁时数据操作应该正常")
        
        print("   ✅ 锁机制测试通过")


def run_comprehensive_test():
    """运行综合测试"""
    print("🚀 存储引擎综合功能测试")
    print("=" * 70)
    
    # 创建测试套件
    suite = unittest.TestLoader().loadTestsFromTestCase(ComprehensiveStorageTest)
    
    # 自定义测试结果类，用于更好的输出
    class CustomTestResult(unittest.TextTestResult):
        def startTest(self, test):
            super().startTest(test)
            
        def addSuccess(self, test):
            super().addSuccess(test)
            
        def addError(self, test, err):
            super().addError(test, err)
            print(f"   ❌ {test._testMethodName} 错误: {err[1]}")
            
        def addFailure(self, test, err):
            super().addFailure(test, err)
            print(f"   ❌ {test._testMethodName} 失败: {err[1]}")
    
    # 运行测试
    runner = unittest.TextTestRunner(
        verbosity=0,
        resultclass=CustomTestResult,
        stream=open(os.devnull, 'w')  # 隐藏默认输出
    )
    
    start_time = time.time()
    result = runner.run(suite)
    total_time = time.time() - start_time
    
    # 输出测试结果汇总
    print("\n" + "=" * 70)
    print("📊 测试结果汇总")
    print("=" * 70)
    
    total_tests = result.testsRun
    failures = len(result.failures)
    errors = len(result.errors)
    success = total_tests - failures - errors
    
    print(f"总测试数: {total_tests}")
    print(f"成功: {success}")
    print(f"失败: {failures}")
    print(f"错误: {errors}")
    print(f"总耗时: {total_time:.2f}秒")
    
    if failures == 0 and errors == 0:
        print("\n🎉 所有测试通过！存储引擎功能完整且正常！")
        print("\n🏆 验证完成的功能:")
        print("  ✅ 页面级存储管理")
        print("  ✅ 多种缓存策略（LRU、FIFO、Clock）")
        print("  ✅ 表结构定义和管理")
        print("  ✅ 多种数据类型支持")
        print("  ✅ 记录级CRUD操作")
        print("  ✅ 条件查询功能")
        print("  ✅ 完整数据持久化")
        print("  ✅ 多表并发操作")
        print("  ✅ 边界情况处理")
        print("  ✅ 性能优化机制")
        return True
    else:
        print(f"\n💥 测试发现问题: {failures + errors}项测试失败")
        if result.failures:
            print("\n失败的测试:")
            for test, traceback in result.failures:
                print(f"  - {test}")
        if result.errors:
            print("\n错误的测试:")
            for test, traceback in result.errors:
                print(f"  - {test}")
        return False


def interactive_test_menu():
    """交互式测试菜单"""
    while True:
        print("\n" + "=" * 50)
        print("存储引擎测试菜单")
        print("=" * 50)
        print("1. 运行完整综合测试")
        print("2. 运行单个测试模块")
        print("3. 性能基准测试")
        print("4. 手动功能验证")
        print("0. 退出")
        
        choice = input("\n请选择 (0-4): ").strip()
        
        if choice == '0':
            break
        elif choice == '1':
            run_comprehensive_test()
        elif choice == '2':
            run_individual_tests()
        elif choice == '3':
            run_benchmark_test()
        elif choice == '4':
            run_manual_verification()
        else:
            print("无效选择")
        
        input("\n按回车继续...")


def run_individual_tests():
    """运行单个测试模块"""
    test_methods = [
        ("基础页操作", "test_01_basic_page_operations"),
        ("缓存策略", "test_02_cache_strategies"),
        ("表结构管理", "test_03_table_schema_management"),
        ("记录CRUD操作", "test_04_record_crud_operations"),
        ("数据持久化", "test_05_data_persistence"),
        ("数据类型处理", "test_06_data_types_handling"),
        ("多表操作", "test_07_multiple_tables"),
        ("性能测试", "test_08_performance_test"),
        ("边界情况", "test_09_edge_cases")
    ]
    
    print("\n可用的测试模块:")
    for i, (name, _) in enumerate(test_methods, 1):
        print(f"{i}. {name}")
    
    try:
        choice = int(input("\n请选择测试模块 (1-9): "))
        if 1 <= choice <= len(test_methods):
            name, method_name = test_methods[choice - 1]
            print(f"\n运行 {name} 测试...")
            
            suite = unittest.TestSuite()
            test_case = ComprehensiveStorageTest(method_name)
            suite.addTest(test_case)
            
            runner = unittest.TextTestRunner(verbosity=2)
            runner.run(suite)
        else:
            print("无效选择")
    except ValueError:
        print("请输入有效数字")


def run_benchmark_test():
    """运行性能基准测试"""
    print("\n🚀 性能基准测试")
    print("-" * 40)
    
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.db')
    db_path = temp_file.name
    temp_file.close()
    
    try:
        with StorageEngine(db_path, cache_size=100) as engine:
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("data1", ColumnType.VARCHAR, length=50),
                Column("data2", ColumnType.FLOAT),
                Column("data3", ColumnType.BOOLEAN)
            ]
            engine.create_table("benchmark", columns)
            
            # 插入性能测试
            sizes = [100, 500, 1000]
            for size in sizes:
                print(f"\n测试 {size} 条记录:")
                
                start_time = time.time()
                for i in range(size):
                    record = {
                        "id": i,
                        "data1": f"测试数据_{i}",
                        "data2": float(i * 1.5),
                        "data3": i % 2 == 0
                    }
                    engine.insert_record("benchmark", record)
                
                insert_time = time.time() - start_time
                
                start_time = time.time()
                records = engine.select_records("benchmark")
                query_time = time.time() - start_time
                
                print(f"  插入耗时: {insert_time:.3f}秒 ({size/insert_time:.1f} 记录/秒)")
                print(f"  查询耗时: {query_time:.3f}秒")
                print(f"  缓存命中率: {engine.get_cache_stats().hit_rate:.1%}")
                
                # 清理数据准备下一轮测试
                engine.drop_table("benchmark")
                engine.create_table("benchmark", columns)
    
    finally:
        if os.path.exists(db_path):
            os.unlink(db_path)


def run_manual_verification():
    """手动功能验证"""
    print("\n🔧 手动功能验证")
    print("-" * 40)
    
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.db')
    db_path = temp_file.name
    temp_file.close()
    
    try:
        with StorageEngine(db_path) as engine:
            print("✅ 存储引擎初始化成功")
            
            # 创建示例表
            columns = [
                Column("id", ColumnType.INT, primary_key=True),
                Column("name", ColumnType.VARCHAR, length=50),
                Column("score", ColumnType.FLOAT)
            ]
            
            success = engine.create_table("test_table", columns)
            print(f"✅ 创建表: {'成功' if success else '失败'}")
            
            # 插入示例数据
            test_data = [
                {"id": 1, "name": "张三", "score": 95.5},
                {"id": 2, "name": "李四", "score": 87.0},
                {"id": 3, "name": "王五", "score": 92.3}
            ]
            
            for record in test_data:
                success = engine.insert_record("test_table", record)
                print(f"✅ 插入记录 {record['name']}: {'成功' if success else '失败'}")
            
            # 查询数据
            records = engine.select_records("test_table")
            print(f"✅ 查询到 {len(records)} 条记录")
            
            for record in records:
                print(f"   ID: {record['id']}, 姓名: {record['name']}, 分数: {record['score']}")
            
            # 显示系统信息
            storage_stats = engine.get_storage_stats()
            cache_stats = engine.get_cache_stats()
            
            print(f"\n📊 系统状态:")
            print(f"   总页数: {storage_stats.total_pages}")
            print(f"   已用页数: {storage_stats.used_pages}")
            print(f"   缓存命中率: {cache_stats.hit_rate:.1%}")
            print(f"   当前表数: {len(engine.get_table_list())}")
    
    finally:
        if os.path.exists(db_path):
            os.unlink(db_path)


if __name__ == "__main__":
    print("存储引擎综合测试系统")
    print("=" * 70)
    
    mode = input("选择模式:\n1. 自动运行完整测试\n2. 交互式测试菜单\n请选择 (1-2): ").strip()
    
    if mode == '1':
        success = run_comprehensive_test()
        if success:
            print("\n🎯 所有功能测试通过，存储引擎工作正常！")
        else:
            print("\n⚠️  发现问题，请检查失败的测试项。")
    else:
        interactive_test_menu()
    
    print("\n👋 测试程序结束")
